package com.draw.cli.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

import com.draw.core.User;

public class ConfigManager extends HashMap<String, Object> {
	private static final long serialVersionUID = -3263836956552561051L;

	private static final ConfigManager instance = new ConfigManager();

	private static final String IP_SERVER = "network.server.ip";
	private static final String PORT_SERVER = "network.server.port";
	private static final int DEFAULT_PORT_SERVER = 8080;
	private static final String USERNAME = "ident.username";
	private static final String PASSWORD = "ident.password";
	private static final String PROXY_ENABLED = "network.proxy.enabled";
	private static final String PROXY_SERVER = "network.proxy.server";
	private static final String PROXY_PORT = "network.proxy.port";

	public static ConfigManager getInstance() {
		return instance;
	}

	private User currentUser;

	private ConfigManager() {
		super();
		if (!this.load()) {
			this.setIpServer("127.0.0.1");
			this.setPortServer(8080);
		}
		this.currentUser = null;
	}
	
	public Object put (String key, Object val) {
		Object o = super.put(key, val);
		this.save();
		return o;
	}

	public String getIpServer() {
		return (String) this.get(IP_SERVER);
	}

	public void setIpServer(String ipServer) {
		this.put(IP_SERVER, ipServer);
	}

	public int getPortServer() {
		if (!this.containsKey(PORT_SERVER)) {
			return DEFAULT_PORT_SERVER;
		}
		return (Integer) this.get(PORT_SERVER);
	}

	public void setPortServer(int portServer) {
		this.put(PORT_SERVER, new Integer(portServer));
	}

	public User getCurrentUser() {
		return this.currentUser;
	}

	public void setCurrentUser(User user) {
		this.currentUser = user;
		if (user != null) {
			this.setUsername(user.getUsername());
			this.setPassword(user.getPassword());
		}
	}

	public String getUsername() {
		return (String) this.get(USERNAME);
	}

	public void setUsername(String username) {
		this.put(USERNAME, username);
	}

	public String getPassword() {
		return (String) this.get(PASSWORD);
	}

	public void setPassword(String password) {
		this.put(PASSWORD, password);
	}

	private File getSaveFile() {
		String sep = System.getProperty("file.separator");
		String home = System.getProperty("user.home");
		String filename = home + sep + "drawClient.dat";
		return new File(filename);
	}

	public void setProxyEnabled(boolean val) {
		this.put(PROXY_ENABLED, new Boolean(val));
		this.configProxy();
	}

	public boolean isProxyEnabled() {
		if (this.containsKey(PROXY_ENABLED)) {
			return (Boolean) this.get(PROXY_ENABLED);
		}
		return false;
	}

	public void setProxyServer(String val) {
		this.put(PROXY_SERVER, val);
		this.configProxy();
	}

	public String getProxyServer() {
		if (this.containsKey(PROXY_SERVER)) {
			return (String) this.get(PROXY_SERVER);
		}
		return "";
	}

	public void setProxyPort(int val) {
		this.put(PROXY_PORT, new Integer(val));
		this.configProxy();
	}

	public int getProxyPort() {
		if (this.containsKey(PROXY_PORT)) {
			return (Integer) this.get(PROXY_PORT);
		}
		return 0;
	}

	private void configProxy() {
		if (this.isProxyEnabled()) {
			System.setProperty("http.proxyHost", this.getProxyServer());
			System.setProperty("http.proxyPort", ""+this.getProxyPort());
		} else {
			System.setProperty("http.proxyHost", "");
			System.setProperty("http.proxyPort", "");
		}
	}

	public boolean load() {
		try {
			ObjectInputStream obj = new ObjectInputStream(new FileInputStream(
					this.getSaveFile()));
			ConfigManager conf = (ConfigManager) obj.readObject();
			this.putAll(conf);
			obj.close();
			return true;
		} catch (IOException | ClassNotFoundException e) {
			return false;
		} finally {
			this.configProxy();
		}
	}

	public void save() {
		try {
			ObjectOutputStream obj = new ObjectOutputStream(
					new FileOutputStream(this.getSaveFile()));
			obj.writeObject(this);
			obj.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
